#include "build_table.h"


void initTable(vector<vector<int>> &table)
{
    for(int i=0;i<table.size();i++)
    {
        for(int j=0;j<table[0].size();j++)
        {
            table[i][j]=1;
        }
    }
}


void fillTable(vector<int> &randNum,int range,vector<vector<int>> &table,int col,int num)
{
    for(int i=0;i<randNum.size();i++)
    {
        randNum[i]=0;
    }
    for(int i=0;i<3;i++)
    {
        randNum[i]=rand()%range;
        for(int j=0;j<i;j++)
        {
            if(randNum[i]==randNum[j])
            {
                i--;
                break;
            }
        }
    }


    for(int i=0;i<3;i++)
    {
        for(int j=0;j<num;j++)
        {
            if(j+col<table[0].size())
            {
                table[randNum[i]][j+col]=0;
            }
        }
    }
}

void readBranch(vector<Branch> &branch,string branchFile)
{
    ifstream infile;
    infile.open(branchFile,ios::in);
    if(!infile.is_open())
    {
        cout<<"Open "<<branchFile<<" failure!"<<endl;
        return ;
    }
    int branch_num=0;
    while (!infile.eof())
    {
        Branch b;
        infile>>b.start>>b.end>>b.res>>b.rea>>b.max_p>>b.max_c>>b.source>>b.status>>b.partition;
        b.len=b.choose=0;
        b.num=branch_num++;
        branch.push_back(b);
    }
    infile.close();
}

void buildSwitchBranch(vector<Branch> &branch,vector<Branch> &switchBranch,string switchFile)
{
    ifstream infile;
    infile.open(switchFile,ios::in);
    if(!infile.is_open())
    {
        cout<<"Open "<<switchFile<<" failure!"<<endl;
        return ;
    }
    int switch_num=0;
    while (!infile.eof())
    {
        //起点 终点 0 分区
        int start,end,x,y;
        infile>>start>>end>>x>>y;
        for(int i=0;i<branch.size();i++)
        {
            if((branch[i].start==start&&branch[i].end==end) || (branch[i].start==end&&branch[i].end==start))
            {
                branch[i].choose=1;
                switch_num++;
                switchBranch.push_back(branch[i]);
            }
        }
    }
    infile.close();
    //printBranch(branch);
}




void printBranch(vector<Branch> &branch)
{
    cout<<"序号 起点 终点   电阻    电抗  最大有功功率 最大电流 源 线路状态 分区 长度 闭合"<<endl;
    for(int i=0;i<branch.size();i++)
    {
        cout<<" "<<std::left<<setw(5)<<branch[i].num<<std::left<<setw(5)<<branch[i].start<<std::left<<setw(5)<<branch[i].end<<std::left<<setw(9)
        <<branch[i].res<<std::left<<setw(12)<<branch[i].rea<<std::left<<setw(9)<<branch[i].max_p<<std::left<<setw(7)<<branch[i].max_c
        <<std::left<<setw(6)<<branch[i].source<<std::left<<setw(7)<<branch[i].status<<std::left<<setw(5)<<branch[i].partition<<std::left<<setw(5)
        <<branch[i].len<<std::left<<setw(1)<<branch[i].choose<<endl;
    }
}

void printTable(vector<vector<int>> &table)
{
    for(int i=0;i<table.size();i++)
    {
        for(int j=0;j<table[0].size();j++)
        {
            cout<<table[i][j]<<" ";
        }
        cout<<endl;
    }
}




void printUDN(AMGrpha &G)
{
    for(int i=0;i<G.arcs.size();i++)
    {
        for(int j=0;j<G.arcs[0].size();j++)
        {
            cout<<G.arcs[i][j]<<" ";
        }
        cout<<endl;
    }
}

void DFS(AMGrpha &G,vector<int> &visit,int startNode,int group)
{
    visit[startNode]=group;
    for(int k=1;k<=G.vexnum;k++)
    {
        if((G.arcs[startNode][k]!=0)&&(visit[k]==0))
        {
            DFS(G,visit,k,group);
        }
    }
}

void creatUDN(AMGrpha &G,vector<Branch> &branch)
{
    G.vexnum=0;
    G.arcnum=branch.size();
    for(int i=0;i<G.arcnum;i++)
    {
        if(branch[i].start>G.vexnum)
        {
            G.vexnum=branch[i].start;
        }
        if(branch[i].end>G.vexnum)
        {
            G.vexnum=branch[i].end;
        }
    }
    // cout<<"vexnum "<<G.vexnum<<endl;
    // cout<<"arcnum "<<G.arcnum<<endl;
    vector<int> x(G.vexnum+1,0);
    for(int i=0;i<=G.vexnum;i++)
    {
        G.arcs.push_back(x);
    }

    for(int i=0;i<branch.size();i++)
    {
        G.arcs[branch[i].start][branch[i].end]=G.arcs[branch[i].end][branch[i].start]=1;
    }

    //printUDN(G);

}


bool testTable(AMGrpha &G,vector<vector<int>> &table,vector<Branch> &switchBranch,vector<int> &powerNode)
{
    //cout<<G.arcs.size()<<"   "<<G.arcs[0].size()<<endl;


    //printBranch(switchBranch);

    for(int i=0;i<table[0].size();i++)
    {
        AMGrpha copyG=G;
        vector<int> visit(G.vexnum+1,0);
        int group=0;
        //change UDN
        for(int j=0;j<table.size();j++)
        {
            if(table[j][i]==0)
            {
                copyG.arcs[switchBranch[j].start][switchBranch[j].end]=copyG.arcs[switchBranch[j].end][switchBranch[j].start]=0;
            }
        }

        //DFS
        for(int i=1;i<=G.vexnum;i++)
        {
            if(visit[i]==0)
            {
                group++;
                DFS(copyG,visit,i,group);
            }

        }

        vector<int> record(group+1);
        for(int i=0;i<powerNode.size();i++)
        {
            // cout<<visit[powerNode[i]]<<" ";
            record[visit[powerNode[i]]]++;
        }
        // cout<<endl;


        for(int i=1;i<record.size();i++)
        {
            if(record[i]==0)
            {
                return false;
                break;
            }
        }


        // //print visit
        // for(int i=0;i<visit.size();i++)
        // {
        //     cout<<visit[i]<<" ";
        // }
        // cout<<endl<<endl<<endl;


    }

    // cout<<endl<<endl;
    //printUDN(G);

    return true;



}

bool findPower(vector<int> &powerNode,int num)
{
    for(int i=0;i<powerNode.size();i++)
    {
        if(num==powerNode[i])
        {
            return true;
        }
    }
    return false;
}


void build(vector<Branch> &branch,int N_on,int N_off,vector<vector<int>> &table,vector<Branch> &switchBranch)
{
    srand((int)time(NULL));

    vector<int> v(24,1);
    vector<int> randNum(3);
    vector<int> powerNode;
    AMGrpha G;
    int maxN=max(N_off,N_on);
    
    
    //creat powerNode
    powerNode.push_back(1);
    for(int i=0;i<branch.size();i++)
    {
        if(branch[i].start==1)
        {
            powerNode.push_back(branch[i].end);
        }
        else if(branch[i].end==1)
        {
            powerNode.push_back(branch[i].start);
        }
    }



    //creat graph
    creatUDN(G,branch);


    //creat table
    for(int i=0;i<switchBranch.size();i++)
    {
        table.push_back(v);
    }



    while(true)
    {
        int sum=0;
        initTable(table);
        while(sum<table[0].size())
        {
            int num=(rand()%(table[0].size()-maxN))+maxN;
            fillTable(randNum,switchBranch.size(),table,sum,num);
            // if(sum+num<table[0].size())
            // {
            //     cout<<num<<" ";
            // }
            // else
            // {
            //     cout<<table[0].size()-sum<<" ";
            // }
            sum+=num;
        }
        //cout<<endl;
        

        //cout<<"result "<<testTable(G,table,switchBranch,powerNode)<<endl;

        if(testTable(G,table,switchBranch,powerNode)==true)  
        {
            printTable(table);
            break;
        }
    }

    return ;
}